(display "\n========================================\n")

(define (mul-interval x y)
    (let ((p1 (* (lower-bound x) (lower-bound y)))
          (p2 (* (lower-bound x) (upper-bound y)))
          (p3 (* (upper-bound x) (lower-bound y)))
          (p4 (* (upper-bound x) (upper-bound y))))
         (make-interval (min p1 p2 p3 p4)
                        (max p1 p2 p3 p4))))

; (+,+) (+,+), xlo*ylo, xhi*yhi
; (+,+) (-,+), xhi*ylo, xhi*yhi
; (+,+) (-,-), xhi*ylo, xlo*yhi

; (-,+) (+,+), xlo*yhi, xhi*yhi
; (-,+) (-,+), min(xlo*yhi, xhi*ylo), max(xlo*ylo, xhi*yhi)
; (-,+) (-,-), xhi*ylo, xlo*ylo

; (-,-) (+,+), xlo*yhi, xhi*ylo
; (-,-) (-,+), xlo*yhi, xlo*ylo
; (-,-) (-,-), xhi*yhi, xlo*ylo

(define (mul-interval x y)
    (let ((xlo (lower-bound x))
          (xhi (upper-bound x))
          (ylo (lower-bound y))
          (yhi (upper-bound y)))
        (cond ((and (>= xlo 0) (>= ylo 0))
                (make-interval (* xlo ylo) (* xhi yhi)))
              ((and (>= xlo 0) (<= (* ylo yhi) 0))
                (make-interval (* xhi ylo) (* xhi yhi)))
              ((and (>= xlo 0) (<= yhi 0))
                (make-interval (* xhi ylo) (* xlo yhi)))
              ((and (<= (* xlo xhi) 0) (>= ylo 0))
                (make-interval (* xlo yhi) (* xhi yhi)))
              ((and (<= (* xlo xhi) 0) (<= (* ylo yhi) 0))
                (make-interval (min (* xlo yhi) (* xhi ylo))
                               (max (* xlo ylo) (* xhi yhi))))
              ((and (<= (* xlo xhi) 0) (<= yhi 0))
                (make-interval (* xhi ylo) (* xlo ylo)))
              ((and (<= xhi 0) (>= ylo 0))
                (make-interval (* xlo yhi) (* xhi ylo)))
              ((and (<= xhi 0) (<= (* ylo yhi) 0))
                (make-interval (* xlo yhi) (* xlo ylo)))
              ((and (<= xhi 0) (<= ylo 0))
                (make-interval (* xhi yhi) (* xlo ylo))))))


(define (make-interval a b) (cons a b))
(define (lower-bound z) (car z))
(define (upper-bound z) (cdr z))

(define a (make-interval 2 4))
(define b (make-interval -2 4))
(define c (make-interval -4 -2))

(display (mul-interval a a))
(newline)
(display (mul-interval a b))
(newline)
(display (mul-interval a c))
(newline)
(display (mul-interval b a))
(newline)
(display (mul-interval b b))
(newline)
(display (mul-interval b c))
(newline)
(display (mul-interval c a))
(newline)
(display (mul-interval c b))
(newline)
(display (mul-interval c c))
(newline)
(display "\n========================================\n")
